//
// Created by Suzhen on 2017/2/27.
//

#ifndef ORIONV2_SOCKETIO_H
#define ORIONV2_SOCKETIO_H

#include "FileStream.h"
#include "IOBehavior.h"

ORION_V2_NAMESPACE_BEGIN
        
        //todo 之前socket的对象支持的如 tcpCork 等方法,这里也需要进行支持!
        class SocketIO : public FileStream {
        
        protected:
            SocketIO(FdType fd,
                     const IOBehavior &behavior,
                     uint sockIdleTime,
                     SSL *ssl);
            
            virtual ~SocketIO();
        
        public:
            /**
              * <h2>创建SocketIO, <font color="red">必须使用 closeAsync 进行释放</font></h2>
              */
            static SocketIO *CreateSocket(FdType fd,
                                          const IOBehavior &behavior,
                                          uint sockIdleTime = DEFAULT_STREAM_IDLE_MS,
                                          SSL *ssl = NULL);
            
            /**
             * If you need the kernel to align and buffer packet data over the lifespan of buffers (hence the inability
             * of using writev()), then TCP_CORK should be considered. TCP_CORK is set on a socket file descriptor
             * using the setsockopt() function. When the TCP_CORK option is set, only full packets are sent, until the
             * TCP_CORK option is removed. This is important. To ensure all waiting data is sent, the TCP_CORK option
             * MUST be removed. Herein lies the beauty of the Nagle algorithm. It doesn't require any intervention from
             * the application programmer. But once you set TCP_CORK, you have to be prepared to remove it when there
             * is no more data to send. I can't stress this enough, as it is possible that TCP_CORK could cause subtle
             * bugs if the cork isn't pulled at the appropriate times.
             * @param enable 1启用,0禁用
             */
            void setTcpCork(int enable);
            
            /**
             * 设置是否禁用 nagle 算法
             * @param enable 1启用,0禁用
             */
            void setTcpNoDelay(int enable);
        
        private:
            //normal io
            void NormalStreamIoCallBack(int status, EventFlag ioe);
            
            //ssl io
            void TlsStreamIoCallBack(int status, EventFlag ioe);
        
        protected:
            void onStreamIO(int status, EventFlag ioe) override;
        
        private:
            SSL *sslCtx_;
        };

ORION_V2_NAMESPACE_END


#endif //ORIONV2_SOCKETIO_H
